﻿#include "GAF_Type.h"
#include "GAF_Define.h"
#include "GAF_DeviceCode.h"

namespace GAF
{
	int Power(int nNum, int nPower)
	{
		int _nRtn = nNum;

		if(nPower <= 0)
			return 0;
		else if(nPower == 1){}
		else if(nPower >= 2)
		{
			while(nPower >= 2)
			{
				_nRtn *= nNum;
				nPower--;
			}
		}

		return _nRtn;
	}

	Point	AFG_atFree;
	Size	AFG_sFree;
	Rect	AFG_rFree;
	Colour	AFG_cFree;

	void Point::Set(int x, int y)
	{
		nX = x;
		nY = y;
	}

	void Size::Set(UINT width, UINT height)
	{
		nWidth = width;
		nHeight = height;
	}

	void Rect::Set(int x, int y, UINT width, UINT height)
	{
		nX = x;
		nY = y;
		nWidth = width;
		nHeight = height;
	}

	int Rect::Top(int top)
	{
		if(top != NULL_INT)
		{
			if(top <= nY + (int)nHeight)
			{
				nHeight += nY - top;
				nY = top;
			}
		}
		return nY;
	}

	int Rect::Button(int button)
	{
		if(button != NULL_INT)
		{
			if(button >= nY)
			{
				nHeight = button - nY;
			}
		}
		return nY + nHeight;
	}

	int Rect::Left(int left)
	{
		if(left != NULL_INT)
		{
			if(left <= nX + (int)nWidth)
			{
				nWidth += nX - left;
				nX = left;
			}
		}
		return nX;
	}

	int Rect::Right(int right)
	{
		if(right != NULL_INT)
		{
			if(right >= nX)
			{
				nWidth = right - nX;
			}
		}
		return nX + nWidth;
	}

	Size& Rect::Dimension()
	{
		AFG_sFree.Set(nWidth, nHeight);
		return AFG_sFree;
	}

	Point& Rect::Center()
	{
		AFG_atFree.Set(nX + (nWidth >> 1), nY + (nHeight >> 1));
		return AFG_atFree;
	}

	bool Rect::Intersect(Rect& other)
	{
		GAF_CHECK_R(this != &GAF_RECT_NULL, false);

		if(nX >= other.nX + (int)other.nWidth || nX + (int)nWidth <= other.nX ||
			nY >= other.nY + (int)other.nHeight || nY + (int)nHeight <= other.nY)
			return false;
		return true;
	}

	bool Rect::Contains(Rect& other) 
	{
		GAF_CHECK_R(this != &GAF_RECT_NULL, false);

		if(nX <= other.nX && nX + (int)nWidth >= other.nX + (int)other.nWidth && 
			nY <= other.nY && nY + (int)nHeight >= other.nY + (int)other.nHeight)
			return true;
		return false;
	}

	Rect Rect::Cut(Rect& other)
	{
		GAF_CHECK_R(this != &GAF_RECT_NULL, GAF_RECT_NULL);

		if(!Intersect(other))
			return GAF_RECT_NULL;

		AFG_rFree.nX = GAF_MAX_NUM(nX, other.nX);
		AFG_rFree.nY = GAF_MAX_NUM(nY, other.nY);
		AFG_rFree.nWidth = GAF_MIN_NUM(nX + nWidth, other.nX + other.nWidth) - AFG_rFree.nX;
		AFG_rFree.nHeight = GAF_MIN_NUM(nY + nHeight, other.nY + other.nHeight) - AFG_rFree.nY;

		return AFG_rFree;
	}

	Rect Rect::Compose(Rect& other)
	{
		GAF_CHECK_R(this != &GAF_RECT_NULL, GAF_RECT_NULL);

		AFG_rFree.nX = GAF_MIN_NUM(nX, other.nX);
		AFG_rFree.nY = GAF_MIN_NUM(nY, other.nY);
		AFG_rFree.nWidth = GAF_MAX_NUM(nX + nWidth, other.nX + other.nWidth) - AFG_rFree.nX;
		AFG_rFree.nHeight = GAF_MAX_NUM(nY + nHeight, other.nY + other.nHeight) - AFG_rFree.nY;

		return AFG_rFree;
	}

	bool Rect::operator==(Rect other)
	{
		if(nX == other.nX && nY == other.nY && nWidth == other.nWidth && nHeight == other.nHeight)
			return true;
		return false;
	}

	void Colour::Set(BYTE red, BYTE green, BYTE blue, BYTE alpha)
	{
		nAlpha = alpha;
		nRed = red;
		nGreen = green;
		nBlue = blue;
	}

	Point CreatePoint(int x, int y)
	{
		Point p = {x, y};
		return p;
	}

	Size CreateSize(UINT width, UINT height)
	{
		Size s = {width, height};
		return s;
	}

	Rect CreateRect(int x, int y, UINT width, UINT height)
	{
		Rect r = {x, y, width, height};
		return r;
	}

	Colour CreateColour(BYTE red, BYTE green, BYTE blue, BYTE alpha)
	{
		Colour c = {alpha, red, green, blue};
		return c;
	}


	// 设备状态初始化
	BYTE		DeviceState::bKeyState[GAF_KEY_MAX / 8 + 1];
	BYTE		DeviceState::bCursorState[GAF_CURSOR_MAX / 8 + 1];
	bool		DeviceState::isInit = 
				memset(DeviceState::bKeyState, 0, sizeof(DeviceState::bKeyState) != NULL) &&
				memset(DeviceState::bCursorState, 0, sizeof(DeviceState::bCursorState) != NULL)
				;
	Point		DeviceState::atCursorLast	= {0, 0};

#ifdef GAF_COMMAND_SCEEN
	bool		DeviceState::isSwing		= false;
	Point		DeviceState::atSwingFrist	= {0, 0};
	GAF_DTimeTicks	DeviceState::ttSwingFirst	= 0;
	GAF_DTimeTicks	DeviceState::ttSwingLast	= 0;	
	SwingRecord	DeviceState::vtrSwingRecord;
#endif /*GAF_COMMAND_SCEEN*/
}
